/**
 * Sample Skeleton for "SalaryDisplayAttendance.fxml" Controller Class
 * You can copy and paste this code into your favorite IDE
 **/

package com.pentofab.payrollmanagement.ui.controller;

import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.layout.GridPane;
import javafx.util.Callback;

import com.pentofab.payrollmanagement.application.PayrollApplicationFactory;
import com.pentofab.payrollmanagement.dao.AttendanceDao;
import com.pentofab.payrollmanagement.dao.LeaveDAO;
import com.pentofab.payrollmanagement.dao.impl.LeaveModuleUtility;
import com.pentofab.payrollmanagement.dao.model.AttendanceLeaveDetail;
import com.pentofab.payrollmanagement.dao.model.Company;
import com.pentofab.payrollmanagement.dao.model.Holiday;
import com.pentofab.payrollmanagement.dao.model.UserAccounts;
import com.pentofab.payrollmanagement.exception.BusinessException;
import com.pentofab.payrollmanagement.utilities.Constants;
import com.pentofab.payrollmanagement.utilities.CustomTableConstants;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;


public class SalaryDisplayAttendanceControler extends AbstractUIController implements FormValidator,
     Initializable {

    @FXML
    private GridPane grid;
    @FXML
    private ChoiceBox<String> month;
    @FXML
    private ChoiceBox<String> year;
    @FXML
    private TableView<ObservableList<StringProperty>> tableView;
    
    private Company company;
    private UserAccounts userAccounts;
    private AttendanceDao attendanceDao = PayrollApplicationFactory.getAttandanceMgmt();
    private LeaveDAO leaveDAO = PayrollApplicationFactory.getLeaveDAO();
    private TableColumn<AttendanceLeaveDetail, String>[] tableColmns = null;
    
    ScrollPane scrollpane1 = new ScrollPane(); 
    
    public void view() {
    	
    	scrollpane1.setContent(tableView);
    	String validationMsg = getValidationMessage();
    	if(!validationMsg.equals("")){
    		showError(validationMsg);
    		return;
    	}
    	
    	try {
    		
    	String selyear = year.getSelectionModel().getSelectedItem();
    	int selectedMonths = month.getSelectionModel().getSelectedIndex();
    	int maxDay  = PayRollUtility.getMaxDayofMonth(Integer.parseInt(selyear), selectedMonths);
    	
    	
    	String from_date = "01-"+(selectedMonths+1)+"-"+selyear;
    	String to_date = maxDay+"-"+(selectedMonths+1)+"-"+selyear;		
    	ArrayList<HashMap<String,String>> attDetailList = attendanceDao.employeeTimesheetInfo(null, null, null, from_date,to_date,null, 1);
    	
    	if(attDetailList == null){
    		
    		tableView.getItems().clear();
    		return;
    	}
    		
    		tableView.setEditable(false);
    	    tableView.getItems().clear();
    	    tableView.getColumns().clear();
    	    
    	populateTable(attDetailList,maxDay,from_date);

    	} catch (BusinessException e) {
			e.printStackTrace();
		}
    	
    		
    
    }

    private void populateTable(final ArrayList<HashMap<String, String>> attDetailList, final int maxDays, final String firstDay) {
    	
    	    System.out.println("====================== entering populateTable in =================================");
    	    
    	    final StringBuffer header = new StringBuffer("");
    	    header.append("Id, Name, Company, Dept,HRS,");
    	    for(int i=1;i<=maxDays;i++){
    	    	header.append(i+", ");
    	    }
    	    header.append("Total,Work Days\n - or -\n Hours");
    	    Task<Void> task = new Task<Void>() {
    	      @Override
    	      protected Void call() throws Exception {
    	        if (true) {
    	          final String headerLine =header.toString();
    	          final String[] headerValues = headerLine.split(",");
    	          Platform.runLater(new Runnable() {
    	            @Override
    	            public void run() {
    	              for (int column = 0; column < headerValues.length; column++) {
    	            	  tableView.getColumns().add(
    	                    createColumn(column, headerValues[column].trim()));
    	              }
    	            }
    	          });
    	        }

    	        HashMap<String, String> empInfoDataMap = new HashMap<String, String>();
    	        HashMap<String, HashMap<String, String>> attLeaveHolidayInfoMap = new HashMap<String, HashMap<String, String>>();
    	        
    	        HashMap<String , Integer> empWeekOffInfo = new HashMap<String, Integer>();
    	        HashMap<String, String> hoursPerDayMap =new HashMap<String, String>();
    	        ArrayList<Holiday> holidayDataListFromDB = leaveDAO.getHolidays();
    	        
    	        ArrayList<String> holidayList =new ArrayList<String>();
    	        
    	        for(int i = 0;i< holidayDataListFromDB.size();i++){
    	        	holidayList.add(holidayDataListFromDB.get(i).getDate());
    	        }
    	        
    	        LinkedHashSet<String> daysOfMontSet = PayRollUtility.getDatesForMonth(maxDays, firstDay);
    	        HashMap<String, String> totalWorkHours = new HashMap<String, String>();
    	       
    	        try{
    	        	
    	        	System.out.println("totalWorkHours : "+totalWorkHours);
    	        	LeaveModuleUtility.megeAttLevHoliData(attDetailList, empInfoDataMap,
    	        	attLeaveHolidayInfoMap, empWeekOffInfo, holidayList, totalWorkHours, hoursPerDayMap,daysOfMontSet);
    	        }catch(Exception e){
    	        	e.printStackTrace();
    	        }
    	        System.out.println("hoursPerDayMap  : "+hoursPerDayMap);
    	        
    	        Iterator<String> empIdIterator  = empInfoDataMap.keySet().iterator();
    	        while (empIdIterator.hasNext()) {
    	        	String empId = empIdIterator.next();
    	        	
    	        	String hoursPerDay = hoursPerDayMap.get(empId);

    	        	StringBuffer rowData= new StringBuffer();
    	        	rowData.append(empInfoDataMap.get(empId));
    	        	rowData.append(","+hoursPerDay);
    	        	HashMap<String, String> attIndoMap = attLeaveHolidayInfoMap.get(empId);
    	        	
    	        	Iterator<String> daySetIterator = daysOfMontSet.iterator();
    	        	
    	        	
    	        	while(daySetIterator.hasNext()){
    	        		
    	        		String date = daySetIterator.next();
    	        		
    	        		rowData.append(",");
    	        		
    	        		if(attIndoMap.get(date) != null){
    	        			
    	        			rowData.append(attIndoMap.get(date));
    	        		}else if(holidayList.contains(date)){
    	        			
    	        			rowData.append("H");
    	        		}else{
    	        			
    	        			if(empWeekOffInfo.get(empId) != null){
    	        				Calendar cal = Calendar.getInstance();
    	        				int empWeekOff = empWeekOffInfo.get(empId);
    	        				
    	        				SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");
    	        				sm.parse(date);
    	        				Date attDate = sm.parse(date);
    	        				cal.setTime(attDate);
    	        				
    	        				if(empWeekOff == cal.get(Calendar.DAY_OF_WEEK) ){

    	        					rowData.append("WO");
    	        				}else{
    	        					rowData.append("A");
    	        				}
    	        				
    	        			}else{
    	        				rowData.append("A");
    	        			}
    	        		}
    	        	}
    	        	rowData.append(", "+maxDays);
    	        	rowData.append(", "+totalWorkHours.get(empId));
    	        	
    	          final String[] dataValues = rowData.toString().split(",");
    	          Platform.runLater(new Runnable() {
    	            @Override
    	            public void run() {
    	              // Add additional columns if necessary:
    	              for (int columnIndex = tableView.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
    	            	  tableView.getColumns().add(createColumn(columnIndex, ""));
    	              }
    	              // Add data to table:
    	              ObservableList<StringProperty> data = FXCollections.observableArrayList();
    	              for (String value : dataValues) {
    	                data.add(new SimpleStringProperty(value));
    	              }
    	              tableView.getItems().add(data);
    	            }
    	          });
    	        }
    	        attDetailList.clear();
	            holidayList.clear();
	            holidayDataListFromDB.clear();
    	        empInfoDataMap.clear();
    	        attLeaveHolidayInfoMap.clear();
    	        return null;
    	      }
    	    };
    	    Thread thread = new Thread(task);
    	    thread.setDaemon(true);
    	    thread.start();
    	    thread.run();
    	    
    	    System.out.println("====================== entering populateTable out =================================");
    	  }

    private TableColumn<ObservableList<StringProperty>, String> createColumn(
    	      final int columnIndex, String columnTitle) {
    	    TableColumn<ObservableList<StringProperty>, String> column = new TableColumn<ObservableList<StringProperty>, String>();
    	    String title;
    	    if (columnTitle == null || columnTitle.trim().length() == 0) {
    	      title = "Column " + (columnIndex + 1);
    	    } else {
    	      title = columnTitle;
    	    }
    	    column.setText(title);
    	    column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<StringProperty>, String>, ObservableValue<String>>() {
    	          @Override
    	          public ObservableValue<String> call(
    	              CellDataFeatures<ObservableList<StringProperty>, String> cellDataFeatures) {
    	            ObservableList<StringProperty> values = cellDataFeatures.getValue();
    	            if (columnIndex >= values.size()) {
    	              return new SimpleStringProperty("");
    	            } else {
    	              return cellDataFeatures.getValue().get(columnIndex);
    	            }
    	          }
    	        });
    	    
    	    if(columnIndex >3){
    	    	column.setSortable(false);
    	    }
    	    column.setEditable(false);
    	    column.resizableProperty().set(false);
    	    return column;
    	  }
    
	public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
    	
    	year.getSelectionModel().selectedIndexProperty()
		.addListener(new ChangeListener<Number>() {

			@Override
			public void changed(ObservableValue arg0, Number arg1,
					Number arg2) {

				month.getSelectionModel().clearSelection();
			}

		});

    }

    public void goBack() {

		if (getParent() != null && getParent().length() > 0) {
			PayrollApplicationFactory.getMainController().showScreen(
					getParent(), false);
		}
	
	}
    
    public void reset() {
    	
  		refreshUI();
  	
  	}
	@Override
	public boolean isValid() {
		return false;
	}

	@Override
	public String getValidationMessage() {
		
		if(year.getSelectionModel().getSelectedIndex() < 0)
		return UIMessages.FROM_YEAR;
		
		if(month.getSelectionModel().getSelectedIndex() < 0)
		return UIMessages.FROM_YEAR;
		return "";
	}

	@Override
	public Parent getView() {
		return grid;
	}

	@Override
	public String getTitle() {
		return "Consilidated Attendance";
	}

	@Override
	public void refreshUI(Object... args) {
		
		 tableView.getItems().clear();
 	     tableView.getColumns().clear();

 	     if (args != null && args.length > 0) {
			Company company = (Company) args[0];
			this.company = company;
			
			if(args.length > 1 && args[1] instanceof UserAccounts){
				userAccounts = (UserAccounts) args[1];
			}
		}
		tableView.getItems().clear();
		this.year.getItems().clear();
		month.getSelectionModel().clearSelection();
		year.getSelectionModel().clearSelection();
		ArrayList<String> yearList = new ArrayList<String>();
		int year = PayRollUtility.getYear() - 1;
		for (int i = 0; i < 5; i++) {
			yearList.add(year + "");
			year++;
		}
		year = PayRollUtility.getYear();
		this.year.getItems().addAll(yearList);
		
	}

}
